package com.gxa.table.service.impl;

import com.gxa.table.dao.*;
import com.gxa.table.entity.City;
import com.gxa.table.entity.Flight;
import com.gxa.table.param.*;
import com.gxa.table.service.TableService;
import com.gxa.table.service.UserService;
import dto.ResultDTO;
import entity.Company;
import entity.Member;
import exception.SystemException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import util.Response;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author fengfeng
 * @version 1.0
 * @description: 差旅service实现
 * @date 2021-05-11 9:23
 */
@Service
public class TableServiceImpl implements TableService {

    @Autowired
    private UserService userService;
    @Resource
    private CityDao cityDao;
    @Resource
    private FlightDao flightDao;
    @Resource
    private MacOrderDao macOrderDao;
    @Resource
    private CompanyDao companyDao;
    @Resource
    private ArtOrderDao artOrderDao;
    @Resource
    private MemberDao memberDao;


    /**
     * 用户信息
     *
     * @return
     */
    @Override
    public ResultDTO userAndOrderMsg() {

        Integer totalNumber; // 总人数
        Integer managerNumber = 0; // 经理总人数
        Integer employeeNumber = 0; // 员工总人数
        Integer adminNumber = 0; // 管理员总人数
        Integer buMenNumber = 0; // 部门经理总人数
        Integer maleNumber = 0; // 性别男的总人数
        Integer femaleNumber = 0; // 性别女的总人数

        List<Member> members = memberDao.findAllNoPage();

        //赋值总人数
        totalNumber = members.size();
        //遍历members
        for (Member member : members) {
            if ("总经理".equals(member.getRole().getRoleName())) {
                managerNumber++;
            }
            if ("部门经理".equals(member.getRole().getRoleName())) {
                buMenNumber++;
            }
            if ("管理员".equals(member.getRole().getRoleName())) {
                adminNumber++;
            }
            if ("普通员工".equals(member.getRole().getRoleName())) {
                employeeNumber++;
            }
            // 1 男 0女 性别
            if (member.getMemberSex() == 1) {
                maleNumber++;
            }
            if (member.getMemberSex() == 0) {
                femaleNumber++;
            }
        }
        //构建UOMVo结果集对象
        UOMVo uomVo = new UOMVo();
        uomVo.setTotalNumber(totalNumber);
        uomVo.setManagerNumber(managerNumber);
        uomVo.setBuMenNumber(buMenNumber);
        uomVo.setAdminNumber(adminNumber);
        uomVo.setEmployeeNumber(employeeNumber);
        uomVo.setEmployeeNumber(employeeNumber);
        uomVo.setFemaleNumber(femaleNumber);
        uomVo.setMaleNumber(maleNumber);
        //返回数据到前端
        return new ResultDTO(200, "查询数据成功", uomVo);
    }

    /**
     * 订单目的地城市分布
     *
     * @return
     */
    @Override
    public ResultDTO orderAndCityDistribute() {
        //第一步 查询所有的城市
        List<City> cities = cityDao.findAll();
        //第二步 创建OCDVo对象
        OCDVo ocdVo;
        //第三步 计算所有订单总数
        Integer total = macOrderDao.count();
        //第四步 创建容器
        List<OCDVo> ocdVos = new ArrayList<OCDVo>();
        //第四步 根据城市的Id查询对应的航班
        for (City city : cities) {
            ocdVo = new OCDVo();
            //获取航班对象
            List<Flight> flights = flightDao.findFlightByCityId(city.getCityId());
            //查询机械订单数
            Integer count = 0;
            for (Flight flight : flights) {
                count += macOrderDao.countByFlightId(flight.getFlightId());
            }
            //设置城市名字
            ocdVo.setMuDiDi(city.getCityName());
            //设置订单总数
            ocdVo.setTotalOrder(count);
            //设置占比
            if ((float) count / total == 0.0) {
                String num1 = 0 + "%";
                ocdVo.setZhanBi(num1);
            } else {
                double num2 = (double) count / (double) total;
                DecimalFormat df = new DecimalFormat("###.##");
                BigDecimal b1 = new BigDecimal(num2);
                ocdVo.setZhanBi(df.format(b1)+ "");
            }

            if (!flights.isEmpty()) {
                //通过航空公司Id查询航空公司
                Company company = companyDao.queryById(flights.get(0).getFlightAirlineId());

                if (company != null) {
                    //设置航空公司
                    ocdVo.setZuiReHangKong(company.getCompanyName());
                }

            }

            System.out.println(ocdVo);
            //添加到集合
            ocdVos.add(ocdVo);
        }
        //排序集合的数据
        Collections.sort(ocdVos, new Comparator<OCDVo>() {
            @Override
            public int compare(OCDVo o1, OCDVo o2) {
                if (o1.getTotalOrder() > o2.getTotalOrder()) {
                    return -1;
                } else if (o1.getTotalOrder() < o2.getTotalOrder()) {
                    return 1;
                } else {
                    return 0;
                }
            }
        });
        //返回数据到前端
        return Response.success(200, "查询成功！", ocdVos);
    }

    /**
     * 出差信息趋势图
     *
     * @param param
     * @return
     */
    @Override
    public ResultDTO chuChaiQuShiTu(CCQSTParam param) {

        if (param.getStartTime() != null) {
            //检验传入的格式是否正确
            String[] str1 = validator(param.getStartTime());
            if (!"00:00:00".equals(str1[1])) {
                throw new SystemException(1001, "开始时间不符合规则-->yyyy-MM-dd 00:00:00");
            }
        }

        if (param.getEndTime() != null) {
            //检验传入的格式是否正确
            String[] str2 = validator(param.getEndTime());
            if (!"23:59:59".equals(str2[1])) {
                throw new SystemException(1001, "结束时间不符合规则-->yyyy-MM-dd 23:59:59");
            }
        }
        if (param.getStartDay() != null) {
            //检验传入的格式是否正确
            String[] str3 = validator(param.getStartDay());
            if (!"00:00:00".equals(str3[1])) {
                throw new SystemException(1001, "开始天数不符合规则-->yyyy-MM-dd 00:00:00");
            }
        }
        if (param.getEndDay() != null) {
            //检验传入的格式是否正确
            String[] str4 = validator(param.getEndDay());
            if (!"23:59:59".equals(str4[1])) {
                throw new SystemException(1001, "开始天数不符合规则-->yyyy-MM-dd 23:59:59");
            }
        }
        List<Integer> yuDingShuLiang = new ArrayList<>();
        List<Integer> chuShouOrderShuLiang = new ArrayList<>();
        List<Integer> orderTotalPrice = new ArrayList<>();
        List<Integer> yuDingRenShu = new ArrayList<>();

        // 根据开始的日期去查询航班
        List<Integer> lists = selectAndCount(param);
        yuDingShuLiang.add(lists.get(0));
        chuShouOrderShuLiang.add(lists.get(1));
        orderTotalPrice.add(lists.get(2));
        yuDingRenShu.add(lists.get(3));

        //将接收的日期字符串转换为日期类型
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {

            Date d1 = null;
            String d2 = null;
            if (param.getStartDay() != null && param.getStartDay() != "") {
                d1 = df.parse(param.getStartDay());
            }

            if (param.getStartTime() != null && param.getStartTime() != "") {
                d1 = df.parse(param.getStartTime());
            }
            if (param.getEndDay() != null && param.getEndDay() != "") {
                d2 = param.getEndDay();
            }

            if (param.getEndTime() != null && param.getEndTime() != "") {
                d2 = param.getEndTime();
            }
            Date nextDate = df.parse("1000-05-01 00:00:00");
            List<Integer> container = new ArrayList<>();
            //将接收的日期字符串转换为日期类型
            SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            while (nextDate.before(df2.parse(d2))) {
                nextDate = getNextDayTime(d1);
                d1 = getNextDay(d1);
                //清空集合元素
                container.clear();
                CCQSTParam ccqstParam = new CCQSTParam();
                ccqstParam.setStartDay(df2.format(d1));
                ccqstParam.setEndDay(df2.format(nextDate));
                // 根据开始的日期去查询航班
                lists = selectAndCount(ccqstParam);
                yuDingShuLiang.add(lists.get(0));
                chuShouOrderShuLiang.add(lists.get(1));
                orderTotalPrice.add(lists.get(2));
                yuDingRenShu.add(lists.get(3));
            }

            CCQSTPVo ccqstpVo = new CCQSTPVo();
            ccqstpVo.setYuDingRenShu(yuDingRenShu);
            ccqstpVo.setChuShouOrderShuLiang(chuShouOrderShuLiang);
            ccqstpVo.setOrderTotalPrice(orderTotalPrice);
            ccqstpVo.setYuDingShuLiang(yuDingShuLiang);
            //返回数据到前端
            return Response.success(200, "查询成功", ccqstpVo);

        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 检验传过来的数据
     */
    public String[] validator(String str) {
        //检验传入的格式是否正确
        String[] split = str.split(" ");
        return split;
    }


    /**
     * 根据日期统计-->预定数量、出售订单数、订单总金额、预定人数
     *
     * @param ccqstParam
     */
    public List<Integer> selectAndCount(CCQSTParam ccqstParam) {

        Integer yuDingShuLiang = 0;
        Integer chuShouOrderShuLiang = 0;
        Integer orderTotalPrice = 0;
        Integer yuDingRenShu = 0;

        //创建容器
        List<Integer> lists = new ArrayList<>();

        // 第一步 预定数量
        List<Flight> flights = flightDao.findByDate(ccqstParam);

        // 遍历flights
        for (Flight flight : flights) {
            //计算预定订单数
            yuDingShuLiang += macOrderDao.yuDinShuLiang(flight.getFlightId());
            yuDingShuLiang += artOrderDao.yuDinShuLiang(flight.getFlightId());
            // 第二步 出售订单数量
            chuShouOrderShuLiang += macOrderDao.chuShouOrderShuLiang(flight.getFlightId());
            chuShouOrderShuLiang += artOrderDao.chuShouOrderShuLiang(flight.getFlightId());
            // 第三步 订单总金额
            orderTotalPrice += macOrderDao.orderTotalPrice(flight.getFlightId());
            // 第四步 预定人数
            yuDingRenShu += macOrderDao.yuDingRenShu(flight.getFlightId());
            yuDingRenShu += artOrderDao.yuDingRenShu(flight.getFlightId());
        }

        lists.add(yuDingShuLiang);
        lists.add(chuShouOrderShuLiang);
        lists.add(orderTotalPrice);
        lists.add(yuDingRenShu);

        return lists;
    }

    /**
     * 进行日期累加
     *
     * @param date
     * @return
     */
    public static Date getNextDayTime(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, +1);//+1今天的时间加一天
        calendar.add(Calendar.HOUR_OF_DAY, +23);//+1今天的小时加12
        calendar.add(Calendar.SECOND, 59);
        calendar.add(Calendar.MINUTE, 59);
        date = calendar.getTime();
        return date;
    }

    /**
     * 进行日期累加
     *
     * @param date
     * @return
     */
    public static Date getNextDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, +1);//+1今天的时间加一天
        date = calendar.getTime();
        return date;
    }

    /**
     * 其它数据
     *
     * @param param
     * @return
     */
    @Override
    public ResultDTO qiTaDataDistribute(QTDDParam param) {
        // 处理时间-->获取年份
        Calendar calendar = Calendar.getInstance();

        if (param.getYear() != null) {

            //获取年份
            Integer paramYear = param.getYear();

            // 根据该年航班Id统计出差次数
            Integer c2 = macOrderDao.countAllYearChuChaiCiShu();
            // 根据该年航班Id统计出差总费用
            Integer p2 = macOrderDao.countAllYearTotalPrice();
            // 根据该年航班Id统计总出票订单量
            Integer o2 = macOrderDao.countAllYearOutOrder();
            // 根据该年航班Id统计总出票订单额
            Integer e2 = macOrderDao.countAllYearOutOrderE();

            return common(c2, p2, o2, e2, paramYear);
        }

        // 人平均出差次数 = 每年的人出差总次数 / 每一个月的人出差总次数

        calendar.setTime(param.getDate());
        Integer year = calendar.get(Calendar.YEAR);

        // 处理时间-->获取月份
        int month = calendar.get(Calendar.MONTH);
        // 根据月份查询航班对象
        List<Flight> lists = flightDao.findByMonth(month + 1);
        Integer c2 = 0;
        Integer p2 = 0;
        Integer o2 = 0;
        Integer e2 = 0;
        // 遍历航班信息
        for (Flight flight : lists) {
            // 根据月份航班Id统计出差次数
            c2 += macOrderDao.countYearChuChaiCiShu(flight.getFlightId());
            // 根据该月份航班Id统计出差总费用
            p2 += macOrderDao.countMonthTotalPrice(flight.getFlightId());
            // 根据月份航班Id统计总出票订单量
            o2 += macOrderDao.countYearOutOrder(flight.getFlightId());
            // 根据月份航班Id统计总出票订单额
            e2 += macOrderDao.countYearOutOrderE(flight.getFlightId());

        }

        return common(c2, p2, o2, e2, year);

    }

    /**
     * 公共计算抽取
     *
     * @param year
     * @param c2
     * @param p2
     * @param o2
     * @param e2
     * @return
     */
    public ResultDTO common(Integer c2, Integer p2, Integer o2, Integer e2, Integer year) {

        // 根据年份查询航班对象
        List<Flight> flights = flightDao.findByYear(year.toString());

        Integer c1 = 0;
        Integer p1 = 0;
        Integer o1 = 0;
        Integer e1 = 0;
        // 遍历航班信息
        for (Flight flight : flights) {
            // 根据该年航班Id统计出差次数
            c1 += macOrderDao.countYearChuChaiCiShu(flight.getFlightId());
            // 根据该年航班Id统计出差总费用
            p1 += macOrderDao.countYearTotalPrice(flight.getFlightId());
            // 根据该年航班Id统计总出票订单量
            o1 += macOrderDao.countYearOutOrder(flight.getFlightId());
            // 根据该年航班Id统计总出票订单额
            e1 += macOrderDao.countYearOutOrderE(flight.getFlightId());

        }

        int renPinJunChuChaiCiShu = 0;
        if (c2 != 0) {
            // c1/c2除不尽向上取整
            renPinJunChuChaiCiShu = (int) Math.ceil(c1 * 1.0 / c2);
        }
        int setRenPinJunChuChaiFeiYong = 0;
        if (p2 != 0) {
            setRenPinJunChuChaiFeiYong = Math.round(p1 / p2);
        }
        int zongChuPiaoOrderLiang = 0;
        if (o2 != 0) {
            zongChuPiaoOrderLiang = (int) Math.ceil(o1 * 1.0 / o2);
        }
        int zongChuPiaoOrderJinE = 0;
        if (e2 != 0) {
            zongChuPiaoOrderJinE = Math.round(e1 / e2);
        }
        //组装对象
        QTDDVo qtddVo = new QTDDVo();
        qtddVo.setRenPinJunChuChaiCiShu(renPinJunChuChaiCiShu);
        qtddVo.setRenPinJunChuChaiFeiYong(setRenPinJunChuChaiFeiYong);
        qtddVo.setZongChuPiaoOrderJinE(zongChuPiaoOrderJinE);
        qtddVo.setZongChuPiaoOrderLiang(zongChuPiaoOrderLiang);
        //返回数据到前端
        return Response.success(200, "success", qtddVo);
    }

}